#include "dns.h"

#include <winsock2.h>
#include <ws2tcpip.h>

// link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")

dns::dns(void)
{
	WSADATA wsaData;
	int iResult;

	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
}


dns::~dns(void)
{
	WSACleanup();
}

string dns::resolve(const string& host) const
{
	struct addrinfo *result = NULL;
	struct addrinfo *ptr = NULL;
	struct addrinfo hints;
	struct sockaddr_in  *sockaddr_ipv4;
	DWORD dwRetval;

	//--------------------------------
	// Setup the hints address info structure
	// which is passed to the getaddrinfo() function
	ZeroMemory( &hints, sizeof(hints) );
	hints.ai_family = AF_INET; // ipv4 only
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;


	//--------------------------------
	// Call getaddrinfo(). If the call succeeds,
	// the result variable will hold a linked list
	// of addrinfo structures containing response
	// information
	dwRetval = getaddrinfo(host.c_str(), NULL, &hints, &result);
	if ( dwRetval != 0 ) {
		//printf("getaddrinfo failed with error: %d\n", dwRetval);
		//WSACleanup();
		return "";
	}

	ptr = result;
	if(ptr)
	{
		sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
		//printf("\tIPv4 address %s\n", inet_ntoa(sockaddr_ipv4->sin_addr) );
		string s = inet_ntoa(sockaddr_ipv4->sin_addr);
		freeaddrinfo(result);

		return s;
	}
	else
	{
		return "";
	}
}

unique_ptr<dns> dns::s_instance;

// NOTE: it is not thread safty and DONOT delete the pointer after use!
dns* dns::instance()
{
	if(!s_instance)
	{
		s_instance.reset(new dns());
	}
	return s_instance.get();
}